<template>
  <div class="rel leftmenu hmax">
    <ResizableGrid>
      <div class="wmax hmax bgwh leftmenu-nav">
        <div class="search">
          <div class="addField">
            <el-button @click="addField" type="text" icon="el-icon-circle-plus"
              >添加字段</el-button
            >
          </div>
          <el-input
            v-model="filterText"
            placeholder="按名称查询"
            clearable
            :maxlength="64"
            prefix-icon="el-icon-search"
          />
        </div>
        <div class="leftmenu-nav-tree mt10">
          <el-tree
            class="filter-tree"
            :data="data"
            :props="defaultProps"
            default-expand-all
            :filter-node-method="filterNode"
            ref="tree"
            node-key="id"
          >
            <span
              class="custom-tree__node"
              slot-scope="{ node, data }"
              :style="{ cursor: node.isLeaf ? 'move' : 'pointer' }"
              @mousedown="(e) => onDragStart(e, node)"
            >
              <span
                :title="`${node.label}(${data.code})`"
                class="custom-tree__span"
              >
                <i v-if="!!data.isCustom" class="el-icon-user"></i>
                {{ `${node.label}(${data.code})` }}</span
              >
              <el-dropdown
                placement="bottom"
                v-if="data.isCustom"
                @command="handleOrgCommand($event, data)"
              >
                <i style="cursor: pointer" class="el-icon-more" />
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item command="edit" icon="el-icon-edit"
                    >编辑</el-dropdown-item
                  >
                  <el-dropdown-item command="delete" icon="el-icon-delete"
                    >删除</el-dropdown-item
                  >
                </el-dropdown-menu>
              </el-dropdown>
            </span>
          </el-tree>
        </div>
      </div>
    </ResizableGrid>
    <AddField
      :subTableTreeData="subTableTreeData"
      :fieldList="data"
      ref="addFieldModal"
      @ok="syncData"
    />
  </div>
</template>
<script>
import ResizableGrid from "@/components/ResizableGrid"
import Excel from "./rightModel/excel/index"
import { getHmentitymodelListTree } from "@/apis/paas/HmEntityModelController.js"
import { cloneDeep } from "lodash"
import { breadFirstTree, getTreeNodeById } from "@/utils/util"
import AddField from "./AddField.vue"
const FORMAT_MAP = {
  DATE: {
    formatType: "datetimeSeconds",
    formatReg: "yyyy-MM-dd HH:mm",
  },
  NUMBER: {
    dataType: "number",
    unit: "",
    limitNumber: 0,
    showSeparator: false,
    isPercent: false,
  },
}
export default {
  components: {
    ResizableGrid,
    AddField,
  },
  props: ["modelCode"],
  data() {
    return {
      filterText: "",
      data: [],
      defaultProps: {
        children: "children",
        label: "ExpressionName",
      },
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    },
  },
  computed: {
    //子表树
    subTableTreeData() {
      let treeData = cloneDeep(this.data).filter((i) => i.type === "SUB_TABLE")
      breadFirstTree(
        treeData,
        (node) => {
          node.children = node.children
            ? node.children.filter((i) => i.type === "SUB_TABLE")
            : []
          return true
        },
        "children"
      )
      return treeData
    },
  },
  mounted() {
    this.getTreeData()
  },
  methods: {
    //获取字段树
    async getTreeData() {
      const data = await getHmentitymodelListTree({
        modelCode: this.modelCode,
      })
      breadFirstTree(
        data,
        (node) => {
          node.Expression = node.Expression || node.code
          node.ExpressionName = node.ExpressionName || node.name
          node.FieldLabel = "${" + node.ExpressionName + "}"
          node.children.forEach((child) => {
            child.Expression = `${node.Expression}.${child.code}`
            child.ExpressionName = `${node.ExpressionName}.${child.name}`
          })
          return true
        },
        "children"
      )
      this.data = data
      let customFieldList = Excel.handsontableHelper.getCustomFieldList()
      let items = this.mergeTreeData(customFieldList)
      Excel.updateCustomFieldList(items, items, "update")
    },
    filterNode(value, data) {
      if (!value) return true
      return data.ExpressionName.indexOf(value) !== -1
    },
    //拖拽动作
    onDragStart(e, info) {
      if (!info.isLeaf) return
      Excel.clearCurrentMouseOverCell()
      const n = document.createElement("div")
      n.innerText = info.data.FieldLabel
      n.id = "dragging-item"
      n.classList.add("dragging")
      n.style.left = e.pageX - 35 + "px"
      n.style.top = e.pageY - 10 + "px"
      let r = null
      let i = false
      const a = (e) => {
        i = true
        n.style.left = e.pageX - 35 + "px"
        n.style.top = e.pageY - 10 + "px"
        r = Excel.currentMouseOverCell
      }
      const s = () => {
        n.remove()
        document.removeEventListener("mouseover", a)
        Excel.toggleAdd(false)
        if (r && i) {
          if (r.row < 0 || r.col < 0) {
            return (i = false)
          }
          Excel.setCellsExpression([
            [
              r.row,
              r.col,
              {
                parentCode: info.data.parentCode,
                parentId: info.data.parentId,
                isCustom: info.data.isCustom,
                FieldLabel: info.data.FieldLabel,
                Expression: info.data.Expression,
                MetaDataID: info.data.Expression,
                RootMetaDataID: info.data.Expression,
                Format: info.data.type,
                FormatConfig:
                  FORMAT_MAP[info.data.type] &&
                  JSON.stringify(FORMAT_MAP[info.data.type]),
              },
            ],
          ])
          i = false
        }
      }

      document.addEventListener("mouseover", a)
      document.addEventListener("mouseup", s)
      n.addEventListener("mouseup", s)
      document.body.appendChild(n)
      Excel.toggleAdd(true)
    },
    // 添加自定义字段
    addField() {
      this.$refs.addFieldModal.add()
    },
    editField(item) {
      this.$refs.addFieldModal.edit(item)
    },
    // 同步自定义字段
    syncData({ fieldData, isNew }) {
      let customFieldList = Excel.handsontableHelper.getCustomFieldList()
      let item = {}
      if (isNew) {
        item = this.mergeTreeData([fieldData])[0]
        customFieldList.push(item)
      } else {
        if (fieldData.parentId) {
          //子表下的字段
          let subtable =
            getTreeNodeById(this.data, fieldData.parentId, "children") || {}
          for (let i = 0; i < subtable.children.length; i++) {
            if (subtable.children[i].id === fieldData.id) {
              this.$set(subtable.children, i, {
                ...fieldData,
                Expression: `${subtable.Expression}.${fieldData.code}`,
                ExpressionName: `${subtable.ExpressionName}.${fieldData.name}`,
                FieldLabel:
                  "${" + `${subtable.ExpressionName}.${fieldData.name}` + "}",
              })
              item = subtable.children[i]
              break
            }
          }
        } else {
          //非子表下的字段
          for (let i = 0; i < this.data.length; i++) {
            if (this.data[i].id === fieldData.id) {
              this.$set(this.data, i, {
                ...fieldData,
                Expression: fieldData.code,
                ExpressionName: fieldData.name,
                FieldLabel: "${" + fieldData.name + "}",
              })
              item = this.data[i]
              break
            }
          }
        }
        //更新excel存的数据
        for (let i = 0; i < customFieldList.length; i++) {
          if (customFieldList[i].id === fieldData.id) {
            customFieldList[i] = item
            break
          }
        }
      }
      //同步excel
      Excel.updateCustomFieldList(
        customFieldList,
        [item],
        isNew ? "add" : "update"
      )
    },
    //自定义字段操作
    handleOrgCommand(command, data) {
      if (command === "edit") {
        this.editField(data)
      } else if (command === "delete") {
        if (data.parentId) {
          let subtable =
            getTreeNodeById(this.data, data.parentId, "children") || {}
          let index = subtable.children.findIndex((i) => i.id === data.id)
          subtable.children.splice(index, 1)
        } else {
          let index = this.data.findIndex((i) => i.id === data.id)
          this.data.splice(index, 1)
        }
        let customFieldList = Excel.handsontableHelper.getCustomFieldList()
        let index = customFieldList.findIndex((i) => i.id === data.id)
        customFieldList.splice(index, 1)
        Excel.updateCustomFieldList(customFieldList, [data], "delete")
      }
    },
    // 合并树节点
    mergeTreeData(customFieldList) {
      let items = []
      customFieldList.forEach((fieldData) => {
        if (fieldData.parentId) {
          let subtable =
            getTreeNodeById(this.data, fieldData.parentId, "children") || {}
          let item = {
            ...fieldData,
            Expression: `${subtable.Expression}.${fieldData.code}`,
            ExpressionName: `${subtable.ExpressionName}.${fieldData.name}`,
            FieldLabel:
              "${" + `${subtable.ExpressionName}.${fieldData.name}` + "}",
          }
          subtable && subtable.children.push(item)
          items.push(item)
        } else {
          let item = {
            ...fieldData,
            Expression: fieldData.code,
            ExpressionName: fieldData.name,
            FieldLabel: "${" + fieldData.name + "}",
          }
          this.data.push(item)
          items.push(item)
        }
      })
      return items
    },
  },
}
</script>
<style lang="scss" scoped>
.wmax {
  width: 100%;
}

.hmax {
  height: 100%;
}

.leftmenu-nav {
  box-sizing: border-box;
  padding: 4px;
  border-right: 1px solid #f1f1f1;
  z-index: 20;

  .addField {
    display: flex;
    justify-content: center;

    ::v-deep button {
      display: flex;
      align-items: center;
      padding: 4px;
    }

    ::v-deep i {
      font-size: 28px;
      color: #f56c6c;
    }

    ::v-deep span {
      font-size: 14px;
      margin-left: 10px;
    }
  }

  &-tree {
    height: calc(100% - 80px);
    overflow-y: auto;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
